package main

import (
	"fmt"
	"sync"
)

func main() {
	NewChinaOnce()
	NewChinaOnce()
	NewChinaOnce()
}

type China struct {
}

/*懒汉式，线程不安全*/
var china *China

func NewChina() *China {
	if china == nil {
		fmt.Println("1949新中国成立")
		china = new(China)
	}
	return china
}

/*懒汉式，线程安全*/
var mutex = sync.Mutex{}

func NewChinaSync() *China {
	mutex.Lock()
	defer mutex.Unlock()
	if china == nil {
		fmt.Println("1949新中国成立")
		china = new(China)
	}
	return china
}

/*饿汉式*/
var chinaInit = new(China)

func NewChinaNotLazy() *China {
	return chinaInit
}

/*DCL*/
func NewChinaDCL() *China {
	if china == nil {
		mutex.Lock()
		defer mutex.Unlock()
		if china == nil {
			fmt.Println("1949新中国成立")
			china = new(China)
		}
	}
	return china
}

/*sync.Once*/
var once = sync.Once{}

func NewChinaOnce() *China {
	once.Do(func() {
		fmt.Println("1949新中国成立")
		china = new(China)
	})
	return china
}
